package com.woniuxy.thred.others;

/**
 * description: LockTest <br>
 * date: 2022/2/6 7:38 下午 <br>
 * author: shesaifei <br>
 * version: 1.0 <br>
 */

/**
 * 可重入锁：锁可以延续使用 +计数器
 */
public class LockTest03 {
    ReLock lock = new ReLock();

    public void a() throws InterruptedException {
        lock.lock();
        System.out.println(lock.getHoldCount());
        doSomething();
        lock.unlock();
        System.out.println(lock.getHoldCount());
    }

    //不可重入
    public void doSomething() throws InterruptedException {
        lock.lock();
        System.out.println(lock.getHoldCount());
        //
        lock.unlock();
        System.out.println(lock.getHoldCount());
    }

    public static void main(String[] args) throws InterruptedException {
        LockTest03 test = new LockTest03();
        test.a();

        Thread.sleep(1000);
        System.out.println(test.lock.getHoldCount());
    }
}

//可重入锁
class ReLock {
    //是否占用
    private boolean isLocked = false;
    //存储线程
    private Thread lockedBy = null;
    private int holdCount = 0;

    //使用锁
    public synchronized void lock() throws InterruptedException {
        Thread t = Thread.currentThread();
        while (isLocked && lockedBy != t) {
            wait();
        }
        isLocked = true;
        lockedBy = t;
        holdCount++;
    }

    //释放锁
    public synchronized void unlock() {
        //当前的线程等于自身
        if (Thread.currentThread() == lockedBy) {
            holdCount--;
            if (holdCount == 0) {
                isLocked = false;
                notify();
                lockedBy = null;
            }
        }
    }

    public int getHoldCount() {
        return holdCount;
    }
}